/* QtLua -- Lua bindings for Qt
   Copyright (C) 2011, Jarek Pelczar

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General
   Public License along with this library; if not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301 USA

*/

#ifndef WRAP_QRECT_H
#define WRAP_QRECT_H

#include <QObject>
#include <QRect>
#include "qluascriptable.h"
#include "qluascriptengine.h"
#include "qluascriptvalue.h"
#include "qluascriptclass.h"
#include "qluaglobal.h"

class QRect_Prototype : public QObject, public QLuaScriptable
{
    Q_OBJECT
    Q_INTERFACES(QLuaScriptable)
    Q_PROPERTY(int left READ left WRITE setLeft)
    Q_PROPERTY(int top READ top WRITE setTop)
    Q_PROPERTY(int right READ right WRITE setRight)
    Q_PROPERTY(int bottom READ bottom WRITE setBottom)
    Q_PROPERTY(int x READ x WRITE setX)
    Q_PROPERTY(int y READ y WRITE setY)
    Q_PROPERTY(QPoint topLeft READ topLeft WRITE setTopLeft)
    Q_PROPERTY(QPoint topRight READ topRight WRITE setTopRight)
    Q_PROPERTY(QPoint bottomLeft READ bottomLeft WRITE setBottomLeft)
    Q_PROPERTY(QPoint bottomRight READ bottomRight WRITE setBottomRight)
    Q_PROPERTY(QPoint center READ center)
    Q_PROPERTY(QSize size READ size WRITE setSize)
    Q_PROPERTY(int width READ width WRITE setWidth)
    Q_PROPERTY(int height READ height WRITE setHeight)
public:
    QRect_Prototype(QObject * parent = 0);

    int left() const { return ptr()->left(); }
    int top() const { return ptr()->top(); }
    int right() const { return ptr()->right(); }
    int bottom() const { return ptr()->bottom(); }
    int x() const { return ptr()->x(); }
    int y() const { return ptr()->y(); }
    void setLeft(int pos) { ptr()->setLeft(pos); }
    void setTop(int pos) { ptr()->setTop(pos); }
    void setRight(int pos) { ptr()->setRight(pos); }
    void setBottom(int pos) { ptr()->setBottom(pos); }
    void setX(int x) { ptr()->setX(x); }
    void setY(int y) { ptr()->setY(y); }
    void setTopLeft(const QPoint &p) { ptr()->setTopLeft(p); }
    void setBottomRight(const QPoint &p) { ptr()->setBottomRight(p); }
    void setTopRight(const QPoint &p) { ptr()->setTopRight(p); }
    void setBottomLeft(const QPoint &p) { ptr()->setBottomLeft(p); }

    QPoint topLeft() const { return ptr()->topLeft(); }
    QPoint bottomRight() const { return ptr()->bottomRight(); }
    QPoint topRight() const { return ptr()->topRight(); }
    QPoint bottomLeft() const { return ptr()->bottomLeft(); }
    QPoint center() const { return ptr()->center(); }

    QSize size() const { return ptr()->size(); }
    int width() const { return ptr()->width(); }
    int height() const { return ptr()->height(); }
    void setWidth(int w) { return ptr()->setWidth(w); }
    void setHeight(int h) { return ptr()->setHeight(h); }
    void setSize(const QSize &s) { ptr()->setSize(s); }

public slots:
    bool isNull() const { return ptr()->isNull(); }
    bool isEmpty() const { return ptr()->isEmpty(); }
    bool isValid() const { return ptr()->isValid(); }

    QRect normalized() const { return ptr()->normalized(); }

    void moveLeft(int pos) { ptr()->moveLeft(pos); }
    void moveTop(int pos) { ptr()->moveTop(pos); }
    void moveRight(int pos) { ptr()->moveRight(pos); }
    void moveBottom(int pos) { ptr()->moveBottom(pos); }
    void moveTopLeft(const QPoint &p) { ptr()->moveTopLeft(p); }
    void moveBottomRight(const QPoint &p) { ptr()->moveBottomRight(p); }
    void moveTopRight(const QPoint &p) { ptr()->moveTopRight(p); }
    void moveBottomLeft(const QPoint &p) { ptr()->moveBottomLeft(p); }
    void moveCenter(const QPoint &p) { ptr()->moveCenter(p); }

    void translate(int dx, int dy) { ptr()->translate(dx, dy); }
    void translate(const QPoint &p) { ptr()->translate(p); }
    QRect translated(int dx, int dy) const { return ptr()->translated(dx, dy); }
    QRect translated(const QPoint &p) const { return ptr()->translated(p); }

    void moveTo(int x, int y) { ptr()->moveTo(x, y); }
    void moveTo(const QPoint &p) { ptr()->moveTo(p); }

    void setRect(int x, int y, int w, int h) { ptr()->setRect(x, y, w, h); }
    void setCoords(int x1, int y1, int x2, int y2) { ptr()->setCoords(x1, y1, x2, y2); }

    void adjust(int x1, int y1, int x2, int y2) { ptr()->adjust(x1, y1, x2, y2); }
    QRect adjusted(int x1, int y1, int x2, int y2) const { return ptr()->adjusted(x1, y1, x2, y2); }

    bool contains(const QPoint &p, bool proper=false) const { return ptr()->contains(p, proper); }
    bool contains(int x, int y) const { return ptr()->contains(x, y); }
    bool contains(int x, int y, bool proper) const { return ptr()->contains(x, y, proper); }
    bool contains(const QRect &r, bool proper = false) const { return ptr()->contains(r, proper); }
    QRect unite(const QRect &r) const { return ptr()->unite(r); }
    QRect united(const QRect &r) const { return ptr()->united(r); }
    QRect intersect(const QRect &r) const { return ptr()->intersect(r); }
    QRect intersected(const QRect &other) const { return ptr()->intersected(other); }
    bool intersects(const QRect &r) const { return ptr()->intersects(r); }

private:
    QRect * ptr() const;
};

class QRectF_Prototype : public QObject, public QLuaScriptable
{
    Q_OBJECT
    Q_INTERFACES(QLuaScriptable)
    Q_PROPERTY(qreal left READ left WRITE setLeft)
    Q_PROPERTY(qreal top READ top WRITE setTop)
    Q_PROPERTY(qreal right READ right WRITE setRight)
    Q_PROPERTY(qreal bottom READ bottom WRITE setBottom)
    Q_PROPERTY(qreal x READ x WRITE setX)
    Q_PROPERTY(qreal y READ y WRITE setY)
    Q_PROPERTY(QPointF topLeft READ topLeft WRITE setTopLeft)
    Q_PROPERTY(QPointF topRight READ topRight WRITE setTopRight)
    Q_PROPERTY(QPointF bottomLeft READ bottomLeft WRITE setBottomLeft)
    Q_PROPERTY(QPointF bottomRight READ bottomRight WRITE setBottomRight)
    Q_PROPERTY(QPointF center READ center)
    Q_PROPERTY(QSizeF size READ size WRITE setSize)
    Q_PROPERTY(qreal width READ width WRITE setWidth)
    Q_PROPERTY(qreal height READ height WRITE setHeight)
public:
    QRectF_Prototype(QObject * parent = 0);

    qreal left() const { return ptr()->left(); }
    qreal top() const { return ptr()->top(); }
    qreal right() const { return ptr()->right(); }
    qreal bottom() const { return ptr()->bottom(); }
    qreal x() const { return ptr()->x(); }
    qreal y() const { return ptr()->y(); }
    void setLeft(qreal pos) { ptr()->setLeft(pos); }
    void setTop(qreal pos) { ptr()->setTop(pos); }
    void setRight(qreal pos) { ptr()->setRight(pos); }
    void setBottom(qreal pos) { ptr()->setBottom(pos); }
    void setX(qreal x) { ptr()->setX(x); }
    void setY(qreal y) { ptr()->setY(y); }
    void setTopLeft(const QPointF &p) { ptr()->setTopLeft(p); }
    void setBottomRight(const QPointF &p) { ptr()->setBottomRight(p); }
    void setTopRight(const QPointF &p) { ptr()->setTopRight(p); }
    void setBottomLeft(const QPointF &p) { ptr()->setBottomLeft(p); }

    QPointF topLeft() const { return ptr()->topLeft(); }
    QPointF bottomRight() const { return ptr()->bottomRight(); }
    QPointF topRight() const { return ptr()->topRight(); }
    QPointF bottomLeft() const { return ptr()->bottomLeft(); }
    QPointF center() const { return ptr()->center(); }

    QSizeF size() const { return ptr()->size(); }
    qreal width() const { return ptr()->width(); }
    qreal height() const { return ptr()->height(); }
    void setWidth(qreal w) { return ptr()->setWidth(w); }
    void setHeight(qreal h) { return ptr()->setHeight(h); }
    void setSize(const QSizeF &s) { ptr()->setSize(s); }

public slots:
    bool isNull() const { return ptr()->isNull(); }
    bool isEmpty() const { return ptr()->isEmpty(); }
    bool isValid() const { return ptr()->isValid(); }

    QRectF normalized() const { return ptr()->normalized(); }

    void moveLeft(qreal pos) { ptr()->moveLeft(pos); }
    void moveTop(qreal pos) { ptr()->moveTop(pos); }
    void moveRight(qreal pos) { ptr()->moveRight(pos); }
    void moveBottom(qreal pos) { ptr()->moveBottom(pos); }
    void moveTopLeft(const QPointF &p) { ptr()->moveTopLeft(p); }
    void moveBottomRight(const QPointF &p) { ptr()->moveBottomRight(p); }
    void moveTopRight(const QPointF &p) { ptr()->moveTopRight(p); }
    void moveBottomLeft(const QPointF &p) { ptr()->moveBottomLeft(p); }
    void moveCenter(const QPointF &p) { ptr()->moveCenter(p); }

    void translate(qreal dx, qreal dy) { ptr()->translate(dx, dy); }
    void translate(const QPointF &p) { ptr()->translate(p); }
    QRectF translated(qreal dx, qreal dy) const { return ptr()->translated(dx, dy); }
    QRectF translated(const QPointF &p) const { return ptr()->translated(p); }

    void moveTo(qreal x, qreal y) { ptr()->moveTo(x, y); }
    void moveTo(const QPointF &p) { ptr()->moveTo(p); }

    void setRect(qreal x, qreal y, qreal w, qreal h) { ptr()->setRect(x, y, w, h); }
    void setCoords(qreal x1, qreal y1, qreal x2, qreal y2) { ptr()->setCoords(x1, y1, x2, y2); }

    void adjust(qreal x1, qreal y1, qreal x2, qreal y2) { ptr()->adjust(x1, y1, x2, y2); }
    QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const { return ptr()->adjusted(x1, y1, x2, y2); }

    bool contains(const QPointF &p) const { return ptr()->contains(p); }
    bool contains(qreal x, qreal y) const { return ptr()->contains(x, y); }
    bool contains(const QRectF &r) const { return ptr()->contains(r); }
    QRectF unite(const QRectF &r) const { return ptr()->unite(r); }
    QRectF united(const QRectF &r) const { return ptr()->united(r); }
    QRectF intersect(const QRectF &r) const { return ptr()->intersect(r); }
    QRectF intersected(const QRectF &other) const { return ptr()->intersected(other); }
    bool intersects(const QRectF &r) const { return ptr()->intersects(r); }

private:
    QRectF * ptr() const;
};

class QRect_wrapper : public QObject, public QLuaScriptClass
{
    Q_OBJECT
    Q_INTERFACES(QLuaScriptClass)
public:
    QRect_wrapper(QLuaScriptEngine * engine);

    virtual QueryFlags queryProperty(const QLuaScriptValue& object,
                                     const QByteArray& name);
    virtual QLuaScriptValue property(const QLuaScriptValue& object,
                                          const QByteArray& name);
    virtual QLuaScriptValue prototype() const;
    virtual QString name() const;

private:
    static QLuaScriptValue QRect_toScriptValue(QLuaScriptEngine * engine, const QRect * t);
    static void QRect_fromScriptValue(const QLuaScriptValue& value, QRect * t);
    static QLuaScriptValue new_rect(QLuaScriptContext *, QLuaScriptEngine *);

private:
    QLuaScriptValue m_proto;
};

class QRectF_wrapper : public QObject, public QLuaScriptClass
{
    Q_OBJECT
    Q_INTERFACES(QLuaScriptClass)
public:
    QRectF_wrapper(QLuaScriptEngine * engine);

    virtual QueryFlags queryProperty(const QLuaScriptValue& object,
                                     const QByteArray& name);
    virtual QLuaScriptValue property(const QLuaScriptValue& object,
                                          const QByteArray& name);
    virtual QLuaScriptValue prototype() const;
    virtual QString name() const;

private:
    static QLuaScriptValue QRectF_toScriptValue(QLuaScriptEngine * engine, const QRectF * t);
    static void QRectF_fromScriptValue(const QLuaScriptValue& value, QRectF * t);
    static QLuaScriptValue new_rectF(QLuaScriptContext *, QLuaScriptEngine *);

private:
    QLuaScriptValue m_proto;
};

#endif // WRAP_QRECT_H
